//npprocess.h
#ifndef _npprocess_h_
#define _npprocess_h_

#if _MSC_VER > 1000
#pragma once
#endif

int OSCreateProcess(const char* cmdLine);
BOOL OSWaitProcess(int pid,BOOL bBlock);
BOOL  OSFindProcess(int pid); //equal to OSWaitProcess(pid,false)
void  OSCloseProcess(int pid);
/* test program
char* progname="c:/calc.exe 8000";
int pid=OSCreateProcess(progname);
BOOL ret=OSFindProcess(pid);
ret=OSWaitProcess(pid,false);
OSWaitProcess(pid,true);
OSCloseProcess(pid);
ret=OSFindProcess(pid);
*/
#if defined(WIN32)
#include <process.h>
inline int OSCreateProcess(const char* cmdLine)
{
	int pid=0;
	PROCESS_INFORMATION pi;
	
	STARTUPINFOA si = {sizeof(si)};
	
	BOOL ret = CreateProcessA(NULL,(char*)cmdLine, NULL,  NULL, FALSE, 0, NULL, NULL, &si, &pi);
	
	if (ret) 
	{
		pid=pi.dwProcessId;	
		CloseHandle(pi.hThread);
	}
	
	return pid;
}

inline BOOL OSFindProcess(int pid)
{
	int bFind=false; 
	HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |  PROCESS_VM_READ, FALSE, pid );
	if ( NULL!=hProcess)
	{
		DWORD  dwRetval = 0;
		if (GetExitCodeProcess(hProcess, &dwRetval)) 
		{
			if (dwRetval == STILL_ACTIVE) 
			{
				bFind=true;
			}
		}
		
		CloseHandle(hProcess);
	}
	return bFind;
}

inline void OSCloseProcess(int pid)
{
	HANDLE hProcess = OpenProcess( PROCESS_TERMINATE, FALSE, pid );
	
	if ( NULL==hProcess ) return;
	TerminateProcess(hProcess,0);
	CloseHandle(hProcess);
}

inline BOOL OSWaitProcess(int pid,BOOL bBlock)
{
    DWORD stat=0;
	BOOL bRet=false;
	DWORD time=bBlock?INFINITE:0;
	
	HANDLE hProcess = OpenProcess( SYNCHRONIZE, FALSE, pid );
	if ( NULL==hProcess )
		return false;

    if ((stat = WaitForSingleObject(hProcess, time)) == WAIT_OBJECT_0)
	{    
	}
    else if (stat == WAIT_TIMEOUT) 
	{
		bRet=true;
    }

	CloseHandle(hProcess);

	//printf("err=%d\n",GetLastError());
	return bRet;
}

#endif //WIN32

#ifdef __linux__
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>

inline char **ParseArgv(const char* cmdLine)
{
	char* prog=(char*)malloc(strlen(cmdLine)+1);
	strcpy(prog,cmdLine);
	int cn=1;
	char* cmd=prog;
	while( (cmd=strchr(cmd,' '))!=NULL)
	{
		*cmd=NULL;
		cmd++;
		while (*cmd==' ') cmd++;
		cn++;
	}
	
	char** ret=(char**)malloc((cn+1)*sizeof(char*));
	
	cmd=prog;
	for(int i=0;i<cn;i++)
	{
		ret[i]=cmd;
		cmd+=(strlen(cmd)+1);
		while (*cmd==' ') cmd++;
	}
	
	ret[cn]=NULL;
	
	return ret;
}

inline int OSCreateProcess(const char* cmdLine)
{
   int pid=0;
   
   pid = fork();

   if ( 0==pid )
   {
		char **cargv=ParseArgv(cmdLine);
		execv(cargv[0], cargv);
		free(cargv[0]);
		free(cargv);
		exit(0);
   }
   else if ( pid>0 )
   {
	   return pid;
   }

   return 0;
}

inline BOOL OSWaitProcess(int pid,BOOL bBlock)
{
	int options=bBlock ? 0 : WNOHANG;
	int id=waitpid(pid,NULL,options);
	return (id==0);
}

inline BOOL OSFindProcess(int pid)
{
	return (0==waitpid(pid,NULL,WNOHANG));
}

inline void OSCloseProcess(int pid)
{
	kill(pid,SIGKILL);	
}
#endif //__linux__

#endif //_npprocess_h_